package com.xixi.canal.client.starter.common;

import com.alibaba.otter.canal.common.utils.BooleanMutex;
import com.xixi.canal.client.starter.config.CanalConfig;
import com.xixi.canal.client.util.StringUtil;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Component
public class SyncSwitch {

    private static final Map<String, BooleanMutex> LOCAL_INSTANCE_LOCK = new ConcurrentHashMap<>();

    @Resource
    private CanalConfig canalConfig;

    @PostConstruct
    public void init() {
        String destinations = canalConfig.getDestinations();
        if (!StringUtil.hasText(destinations)) return;

        String[] instances = destinations.split(",");

        for (String instance : instances) {
            LOCAL_INSTANCE_LOCK.put(instance, new BooleanMutex(true));
        }
    }


    public synchronized void on(String destination) {

        BooleanMutex booleanMutex = LOCAL_INSTANCE_LOCK.get(destination);

        if (null != booleanMutex && !booleanMutex.state()) {
            booleanMutex.set(true);
        }
    }

    public synchronized void off(String destination) {

        BooleanMutex booleanMutex = LOCAL_INSTANCE_LOCK.get(destination);

        if (null != booleanMutex && booleanMutex.state()) {
            booleanMutex.set(false);
        }

    }
    public synchronized void release(String destination) {

        BooleanMutex booleanMutex = LOCAL_INSTANCE_LOCK.get(destination);
        if (null != booleanMutex && !booleanMutex.state()) {
            booleanMutex.set(true);
        }
    }

    public boolean getState(String destination) {

        BooleanMutex booleanMutex = LOCAL_INSTANCE_LOCK.get(destination);

        if (null == booleanMutex) return false;

        return booleanMutex.state();
    }

    public void get(String destination) throws InterruptedException {
        BooleanMutex booleanMutex = LOCAL_INSTANCE_LOCK.get(destination);
        if (null != booleanMutex) booleanMutex.get();
    }
    public void get(String destination, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
        BooleanMutex booleanMutex = LOCAL_INSTANCE_LOCK.get(destination);
        if (null != booleanMutex) booleanMutex.get(timeout, unit);
    }
}
